package org.onion.pattern.notify.wecom;

import ch.qos.logback.core.OutputStreamAppender;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.io.OutputStream;

/**
 * 企业微信日志添加器
 * <pre>

         <appender name="WeCom" class="com.micro.gridvo.framework.env.core.logback.WeComAppender">
         <webhookUrl>https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=20397e1e-827a-49e3-94ed-26674a4f88bb
         </webhookUrl>
         <application>pile</application>
         <enabled>true</enabled>
         <!--        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">-->
         <!--            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">-->
         <!--                <pattern>%boldGreen(%-40.40logger{39}) %m%n-%wEx</pattern>-->
         <!--            </layout>-->
         <!--        </encoder>-->
         <encoder>
         <Pattern>${PATTERN_DEFAULT}</Pattern>
         <charset>utf-8</charset>
         </encoder>
         <filter class="ch.qos.logback.classic.filter.LevelFilter">
         <level>error</level>
         <onMatch>ACCEPT</onMatch>
         <onMismatch>DENY</onMismatch>
         </filter>
         </appender>

 * </pre>
 */
public class WeComAppender<E> extends OutputStreamAppender<E> {

    private String webhookUrl;
    private String msgFormat;
    private String application;
    private String instance;
    private Boolean enabled;

    public void setWebhookUrl(String webhookUrl) {
        this.webhookUrl = webhookUrl;
    }

    public void setMsgFormat(String msgFormat) {
        this.msgFormat = msgFormat;
    }

    public void setApplication(String application) {
        this.application = application;
    }

    public void setInstance(String instance) {
        this.instance = instance;
    }

    public void setEnabled(Boolean enabled) {
        this.enabled = enabled;
    }

    //    protected ConsoleTarget target = ConsoleTarget.SystemOut;
//    protected boolean withJansi = false;

//    private final static String WindowsAnsiOutputStream_CLASS_NAME = "org.fusesource.jansi.WindowsAnsiOutputStream";

//    /**
//     * Sets the value of the <b>Target</b> option. Recognized values are
//     * "System.out" and "System.err". Any other value will be ignored.
//     */
//    public void setTarget(String value) {
//        ConsoleTarget t = ConsoleTarget.findByName(value.trim());
//        if (t == null) {
//            targetWarn(value);
//        } else {
//            target = t;
//        }
//    }
//
//    /**
//     * Returns the current value of the <b>target</b> property. The default value
//     * of the option is "System.out".
//     * <p/>
//     * See also {@link #setTarget}.
//     */
//    public String getTarget() {
//        return target.getName();
//    }
//
//    private void targetWarn(String val) {
//        Status status = new WarnStatus("[" + val + "] should be one of " + Arrays.toString(ConsoleTarget.values()), this);
//        status.add(new WarnStatus("Using previously set target, System.out by default.", this));
//        addStatus(status);
//    }

    @Override
    public void start() {
        WeComOutputStream weComOutputStream = new WeComOutputStream();
        weComOutputStream.setWebhookUrl(this.webhookUrl);
        weComOutputStream.setFormat(this.msgFormat);
        weComOutputStream.setApplication(this.application);
        weComOutputStream.setInstance(this.instance);
//        OutputStream targetStream = target.getStream();
//        // enable jansi only on Windows and only if withJansi set to true
//        if (EnvUtil.isWindows() && withJansi) {
//            targetStream = getTargetStreamForWindows(targetStream);
//        }
        String enabled = System.getenv("LOGBACK_WECOM_ENABLED");

        if (StringUtils.isNotBlank(enabled)) {
            try {
                this.enabled = Boolean.valueOf(enabled);
            } catch (Exception e) {
                //
            }
        }

        if (Boolean.FALSE.equals(this.enabled)) {
            setOutputStream(new OutputStream() {
                @Override
                public void write(int b) throws IOException {
                    //空输出
                }
            });
        } else {
            setOutputStream(weComOutputStream);
        }
        super.start();
    }


//    private OutputStream getTargetStreamForWindows(OutputStream targetStream) {
//        try {
//            addInfo("Enabling JANSI WindowsAnsiOutputStream for the console.");
//            Object windowsAnsiOutputStream = OptionHelper.instantiateByClassNameAndParameter(WindowsAnsiOutputStream_CLASS_NAME, Object.class, context,
//                    OutputStream.class, targetStream);
//            return (OutputStream) windowsAnsiOutputStream;
//        } catch (Exception e) {
//            addWarn("Failed to create WindowsAnsiOutputStream. Falling back on the default stream.", e);
//        }
//        return targetStream;
//    }

//    /**
//     * @return
//     */
//    public boolean isWithJansi() {
//        return withJansi;
//    }
//
//    /**
//     * If true, this appender will output to a stream which
//     *
//     * @param withJansi
//     * @since 1.0.5
//     */
//    public void setWithJansi(boolean withJansi) {
//        this.withJansi = withJansi;
//    }
//

}
